package com.wolfeyes.common.utils.yaml.snakeyaml;

import java.io.InputStream;
import java.util.Collections;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;

import lombok.extern.slf4j.Slf4j;

/**
 * @description 定义yaml手动操作工具类，将 Yaml 文档的操作封装为一个工具类，方便在业务代码中集成
 * @projectName film
 * @className YamlUtil.java
 * @author yanyl
 * @email yanyljava@qq.com
 * @date 2018-07-11 15:53:58
 * @since 2018年07月12日上午11:37:39
 * @createTime 2018年06月09日 下午17:04:13
 * @version 1.0.0
 */
@Slf4j
public class YamlUtils {
    
	/**
	 * @description 从资源文件加载内容，并解析为Map对象
     *
     * @param filePath 文件路径
     * @return Map<String, Object>
     */
	public static Map<String, Object> loadToMap(String filePath) {
		if (StringUtils.isEmpty(filePath)) {
			return Collections.emptyMap();
		}
		
		// 实现加载配置文件
		// 实现从类路径config.yml文件中加载 yaml 配置内容
		InputStream inputStream = YamlUtils.class.getClassLoader().getResourceAsStream(filePath);   
		Yaml yaml = new Yaml();
		Map<String, Object> objectMap = yaml.load(inputStream);
		//System.out.println(objectMap.get("path"));
		return objectMap;
    }
	
	/**
     * @description 将字符串解析为Map对象
     *
     * @param content 内容
     * @return Map<String, Object>
     */
	public static Map<String, Object> parseToMap(String content) {    
		if (StringUtils.isEmpty(content)) {
			return Collections.emptyMap();
        }
		
		Yaml yaml = new Yaml();     
		Map<String, Object> objectMap = yaml.load(content);
		return objectMap;
    }
	
	/**
	 * @title 将 Yaml 文本代码反过来转换为 A 对象
     * @description 将字符串解析为类对象
     * @param content 内容
     * @param clazz 类字节码
     * @param <T> 泛型
     * @return T 泛型
     */
	public static <T> T parseToObject(String content, Class<T> clazz) {
		if (StringUtils.isEmpty(content) || clazz == null) {  
			return null;
        }
		Yaml yaml = new Yaml(new Constructor(clazz));
		T object = yaml.load(content);
		//A a1 = new Yaml().parseToObject(aString, A.class);
		return object;
    }
	
	/**
	 * @title 将指定文件路径下的YAML文本代码反过来转换为 A 对象
     * @description 将文件路径下的YAML文本解析为类对象
     * @param filePath 文件路径
     * @param clazz 类字节码
     * @param <T> 泛型
     * @return T 泛型
     */
	public static <T> T parseToObjectFromPath(String filePath, Class<T> clazz) {
		if (StringUtils.isEmpty(filePath) || clazz == null) {  
			return null;
        }
		
		// 文件路径
		// 实现加载配置文件
		// 实现从类路径config.yml文件中加载 yaml 配置内容
		//InputStream	inputStream = YamlUtils.class.getClassLoader().getResourceAsStream(filePath);
		
		// 从资源文件加载内容，并解析为Map对象
		Map<String, Object> objectMap = YamlUtils.loadToMap(filePath);
		
		// 通过 SnakeYaml 将对象输出为 Yaml 格式的文本代码，并以字符串的形式输出
		String content = YamlUtils.format(objectMap);
		
		// 将字符串解析为类对象
		T object = YamlUtils.parseToObject(content, clazz);
		
		//Yaml yaml = new Yaml(new Constructor(clazz));
		//T object = yaml.load(content);
		//A a1 = new Yaml().parseToObject(aString, A.class);
		return object;
    }
	
	/**
	 * @title 通过 SnakeYaml 将对象输出为 Yaml 格式的文本代码，并以字符串的形式输出
     * @description 格式化对象
     * @param object 对象
     * @return String
     */
	public static String format(Object object) {
		Yaml yaml = new Yaml();
		return yaml.dumpAsMap(object);
    }
	
	/**
	 * @description 测试方法
	 * @param args 入参
	 */
	public static void main(String[] args) throws Exception {
		// 文件路径
		String filePath = "config/application-dev.yml";
		//String filePath = "classpath:config/application-dev.yml";
		//Resource locationResource = new ClassPathResource(filePath);
		//System.out.println(locationResource.getURL());
		//System.out.println(locationResource.getURI());
		//System.out.println(locationResource.getInputStream());
		// 实现加载配置文件
		// 实现从类路径config.yml文件中加载 yaml 配置内容
		InputStream	inputStream = YamlUtils.class.getClassLoader().getResourceAsStream(filePath);
		Yaml yaml = new	Yaml();
		Map<String, Object> objectMap = yaml.load(inputStream);
		//System.out.println(objectMap.get("path"));
		System.out.println(objectMap.get("zqw"));
		// 从资源文件加载内容，并解析为Map对象
		Map<String, Object> objectMap2 = YamlUtils.loadToMap(filePath);
		System.out.println(objectMap2);
		
		Class<ConfigData> clazz = ConfigData.class;
		
		// 通过 SnakeYaml 将对象输出为 Yaml 格式的文本代码，并以字符串的形式输出
		String content = YamlUtils.format(objectMap2);
		System.out.println(content);
		
		// 将字符串解析为类对象
		ConfigData configData = YamlUtils.parseToObject(content, clazz);
		//YamlUtils.parseToObject(content, clazz)
		//System.out.println(configData);
		log.debug("将字符串解析为类对象 ConfigData [{}]", configData);
		
		ConfigData configData2 = YamlUtils.parseToObjectFromPath(filePath, clazz);
		log.debug("将字符串解析为类对象 ConfigData [{}]", configData2);
	}

}


